<?php

namespace Beerus\Modules\DecoCompany\Controllers;

use App\Pockets\GridDataModel as pGridDataModel;
use App\Http\Controllers\Controller;
use Biz\pockets\excel\DownExcel;
use Doraemon\model\DecoCompanyPayService;
use Doraemon\service\DecoCompany\OrderService;
use Doraemon\service\User;
use Doraemon\tools\HhzEnv;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Encore\Admin\Widgets\Form;
use Doraemon\model\DecoCompanyOrder;
use Doraemon\model\Member;
use Doraemon\model\DecoCompanyAuth;
use Doraemon\model\Phone as mPhone;
use Doraemon\service\DecoCompany\DecoCompany as sDecoCompany;
use Doraemon\service\Identifyingcode as sIdentifyingcode;
use Doraemon\tools\ImgUrl;

class OrderController extends Controller
{
    const PAGE_SIZE = 20;

    // 默认实付金额
    const DEFAULT_AMOUNT = 29999;

    const OPERATOR_LIST = [
    	'yangjing',
	    'liziyan',
	    'renyuanxia',
	    'zhouyang',
	    'hujie',
	    'zhiyu',
	    'verawang'
    ];

    // 续费天数分割线
    const RENEWAL_SPLIT_DAY = 90;

    public function __construct()
    {
        parent::__construct();
        Admin::script('$(".pjax-container").attr("id","pjax-container");document.title="装修公司订单";');
    }
    // 列表
    public function index(Request $request,Content $content){
	    Admin::style('.col-md-8{width: 80%}');
	    $params = $request->all();

	    $page_size = $request->input('per_page', self::PAGE_SIZE);
	    $page = $request->input('page', 1);

	    $condition = [];
	    if (!empty($params['uid'])) {
		    $condition['uid'] = $params['uid'];
	    }

	    if (!empty($params['nick'])) {
		    $uid = User::getUidByNick($params['nick']);
		    $condition['uid'] = $uid;
	    }

	    if (!empty($params['pay_status'])) {
		    $condition['pay_status'] = $params['pay_status'];
	    }

	    if (!empty($params['create_time']['start'])) {
		    $condition['create_time[>=]'] = strtotime($params['create_time']['start']. ' 00:00:00');
	    }

	    if (!empty($params['create_time']['end'])) {
		    $condition['create_time[<=]'] = strtotime($params['create_time']['end']. ' 23:59:59');
	    }

	    if (!empty($params['pay_time']['start'])) {
		    $condition['pay_time[>=]'] = strtotime($params['pay_time']['start']. ' 00:00:00');
	    }

	    if (!empty($params['pay_time']['end'])) {
		    $condition['pay_time[<=]'] = strtotime($params['pay_time']['end']. ' 23:59:59');
	    }

	    if (!empty($params['refund_status'])) {
		    $condition['refund_status'] = $params['refund_status'];
	    }

	    if (!empty($params['pay_platform'])) {
		    $condition['pay_platform'] = $params['pay_platform'];
	    }

	    $total = DecoCompanyOrder::count($condition);

	    $lists = [];
	    if ($total) {
		    $condition['ORDER'] = ['id' => 'DESC'];
		    $condition['LIMIT'] = [
			    ($page - 1) * $page_size,
			    $page_size
		    ];

		    $lists = DecoCompanyOrder::select('*', $condition);
		    $user_ids = array_column($lists, 'uid');
		    $member_info = Member::getUsers($user_ids);

		    foreach ($lists as &$item) {
			    $item['nick'] = empty($member_info[$item['uid']]['nick']) ? '' : $member_info[$item['uid']]['nick'];
			    $item['pay_status'] = DecoCompanyOrder::PAY_STATUS_DESC[$item['pay_status']];
			    $item['refund_status'] = DecoCompanyOrder::REFUND_STATUS[$item['refund_status']];
		    }
	    }
        $gridModel = new pGridDataModel($lists, $total, [
            'perPage' => $page_size
        ]);

	    unset($condition['LIMIT']);
	    $search_params = http_build_query($condition);
        $gridList = Admin::grid($gridModel,
            function (Grid $grid) use ($gridModel, $search_params, $condition) {
                $grid->paginate($gridModel->getPerPage());
                $grid->disableExport();
                $grid->disableRowSelector();
                $grid->disableCreateButton();
	            $grid->header(function () use ($condition) {
		            $query = DecoCompanyOrder::select('real_price', $condition);
		            $total_amount = array_sum($query);
		            $total_amount = empty($total_amount) ? 0 : preg_replace('/(?<=[0-9])(?=(?:[0-9]{3})+(?![0-9]))/', ',', $total_amount);
		            return '<b style="color: deepskyblue">订单总数：</b>'. count($query). '<b style="margin-left: 80px; color: deepskyblue">总金额：</b>'. $total_amount;
	            });

	            // 添加录入线下付款按钮
	            $grid->tools(function (Grid\Tools $tool) use ($grid) {
		            $url = url('admin/DecoCompany/order/create');
		            $button = '<div class="btn-group" style="margin-right: 10px">
                        <a class="btn btn-sm btn-primary" href="'.$url.'">
                        <i class="fa fa-paper-plane-o"></i>
                        <span class="hidden-xs">录入付款订单</span></a>
                    </div>';
		            $tool->append($button);
	            });

	            // 添加导出按钮
	            $grid->tools(function (Grid\Tools $tool) use ($grid, $search_params) {
		            $url = url('/admin/DecoCompany/order/export?'. $search_params);
		            $button = '<div class="btn-group download" style="margin-right: 10px">
                        <a class="btn btn-sm btn-primary" target="_blank" href="'.$url.'">
                        <i class="fa fa-download"></i>
                        <span class="hidden-xs">导出订单表</span></a>
                    </div>';
		            $tool->append($button);
	            });

	            $grid->filter(function (Grid\Filter $filter) {
		            $filter->disableIdFilter();
		            $filter->column(1 / 4, function ($filter) {
			            $filter->equal('uid', '用户UID')->placeholder('请输入uid');
		            });
		            $filter->column(1 / 4, function ($filter) {
			            $filter->equal('nick', '用户昵称')->placeholder('请输入昵称');
		            });
		            $filter->column(1 / 4, function ($filter) {
			            $filter->equal('pay_status', '支付状态')->select(DecoCompanyOrder::PAY_STATUS_DESC);
		            });
		            $filter->column(1 / 4, function ($filter) {
			            $filter->equal('refund_status', '退款状态')->select(DecoCompanyOrder::REFUND_STATUS);
		            });
		            $filter->column(1 / 2, function ($filter) {
			            $filter->between('create_time', '录入时间')->date('Y-m-d');
		            });

		            $filter->column(1 / 2, function ($filter) {
			            $filter->between('pay_time', '实际支付时间')->date('Y-m-d');
		            });
		            $filter->column(1 / 4, function ($filter) {
			            $filter->equal('pay_platform', '支付方式')->select(DecoCompanyOrder::PAY_PLATFORM_DESC);
		            });

		            $filter->expand();
	            });

	            $grid->column("dsn", '订单号')->copyable();
                $grid->column("uid", '用户UID')->copyable();
                $grid->column("nick", '昵称')->copyable();
                //$grid->column("package_id", '服务套餐id');
                $grid->column("package_name", '服务套餐名称');
                $grid->column("pay_platform", '支付方式')->display(function () {
                    return DecoCompanyOrder::PAY_PLATFORM_DESC[$this->pay_platform];
                });
	            $grid->column('pay_status', '支付状态')->display(function ($title, Grid\Column $column) {
		            if ($this->pay_status == '已支付') {
			            return $column->label('success');
		            } else if ($this->pay_status == '未支付') {
			            return $column->label('warning');
		            } else if ($this->pay_status == '支付失败') {
			            return $column->label('danger');
		            } else {
			            return '';
		            }
	            })->width(100);
	            $grid->column('refund_status', '退款状态')->display(function ($title, Grid\Column $column) {
		            if ($this->refund_status == '未退款') {
			            return $column->label('success');
		            } else if ($this->refund_status == '已退款') {
			            return $column->label('danger');
		            } else {
			            return '';
		            }
	            });
                $grid->column("certificate_number", '付款凭证编号')->copyable();
	            $grid->column('certificate_number_pic', '付款凭证图片')->display(function () {
		            if (!empty($this->certificate_number_pic)) {
			            $url = ImgUrl::getUrl(ImgUrl::APPTYPE_OP, $this->certificate_number_pic, ImgUrl::IMAGE_SIZE_ORI_NPHONE);
			            $img = "<a href='$url' target='_blank'><img style='box-shadow: 0 0 10px 0 rgba(0, 0, 0, .2)' width='100' height='80' src='{$url}'></a>";
			            return implode('<br/>', [$img]);
		            }
	            });
                $grid->column("real_price", '实付金额（元）');
//                $grid->column("product_price", '商品金额');
//                $grid->column("data_status", '状态')->display(function () {
//                    return DecoCompanyOrder::STATUS_DESC[$this->data_status];
//                });
	            $grid->column('create_time', '录入时间')->display(function() {
		            return date('Y-m-d H:i:s', $this->create_time);
	            });
	            $grid->column('pay_time', '实际支付时间')->display(function() {
		            return date('Y-m-d', $this->pay_time);
	            });
	            $grid->column('start_date', '服务生效时间');
	            $grid->column('end_date', '服务到期时间');
	            $grid->column('admin_uid', '操作人');
	            $grid->actions(function (Grid\Displayers\Actions $actions) {
		            $actions->disableDelete();
	            });
            });

        $tab = new Tab();
        $tab->add('订单列表', $gridList->render());
        $content->row($tab);
        return $content
            ->header('订单列表')
            ->description(' ')
            ->breadcrumb(['text' => '订单列表']);
    }

    // 编辑
    public function edit(Request $request, Content $content, $id = 0)
    {
        $request = $request->all();
        if($id == 0) {
            return $content
                ->header('装修公司 - 订单录入')
	            ->breadcrumb([
		            'text' => '订单列表',
		            'url' => route('order.list'),
	            ], ['text' => '订单录入'])
                ->body(self::editAction($id));
        } else {
            return $content
                ->header('装修公司 - 订单编辑')
                ->breadcrumb([
                    'text' => '订单列表',
                    'url' => route('order.list'),
                ], ['text' => '订单编辑'])
                ->body(self::editAction($id));
        }
    }

    public function editAction($id = 0)
    {
    	$required_text = '不能为空';
        if ($id) {
	        $data = DecoCompanyOrder::get('*', ['id' => $id]);
	        $data['pay_time'] = date('Y-m-d', $data['pay_time']);
	        $form = new Form($data);
	        $form->hidden('id');
	        $form->hidden('uid');
	        $form->display('uid', '用户UID')
		        ->setWidth(5, 2)
		        ->required($required_text)
		        ->help("内部测试号必须用142注册，金额输入0即可");
	        $form->select('package_id', '套餐类型')->setWidth(5, 2)
		        ->options(DecoCompanyOrder::PACKAGE_DESC)
		        ->default(DecoCompanyOrder::PACKAGE_DEFAULT)
		        ->readOnly()
		        ->required($required_text);
	        $form->date('pay_time', '实际支付时间')
		        ->default(date('Y-m-d'))->help('<label style="color: brown">默认为当天，请填写用户实际的付款时间</label>')
		        ->setWidth(5, 2)
		        ->required($required_text)
	            ->readonly();
	        $form->date('start_date', '服务生效时间')
		        ->setWidth(5, 2)
		        ->readonly();
	        $form->date('end_date', '服务到期时间')
		        ->setWidth(5, 2)
		        ->readonly();
	        $form->select('pay_platform', '支付方式')->setWidth(5, 2)
		        ->options(DecoCompanyOrder::PAY_PLATFORM_DESC)
		        ->default(DecoCompanyOrder::PAY_PLATFORM_BANK)
		        ->readOnly()
		        ->required($required_text);
	        $form->display('dsn', '订单号')
		        ->setWidth(5, 2)
		        ->required($required_text);
	        $form->select('pay_status', '支付状态')
		        ->setWidth(5, 2)
		        ->default(DecoCompanyOrder::PAY_STATUS_PAID)
		        ->options(DecoCompanyOrder::PAY_STATUS_DESC)
		        ->required($required_text)
		        ->readOnly();
	        $form->select('refund_status', '退款状态')
		        ->setWidth(5, 2)
		        ->options(DecoCompanyOrder::REFUND_STATUS)
		        ->default(DecoCompanyOrder::NOT_REFUND)->required($required_text);
	        $form->display('real_price', '实付金额（元）')
		        ->setWidth(5, 2)
		        ->required($required_text);
	        $form->display('certificate_number', '付款凭证编号')->setWidth(5, 2)->required($required_text);
	        $form->imgUpload('certificate_number_pic', '付款凭证图片（必传）', false, [
		        'imgType' => ImgUrl::APPTYPE_OP,
		        'imgSize' => ImgUrl::IMAGE_SIZE_OP_ORI,
	        ])->setWidth(5, 2)->readOnly();
        } else {
	        $form = new Form([]);
	        $form->text('uid', '用户UID')->setWidth(5, 2)->required($required_text)
		        ->help("内部测试号必须用142注册，金额输入0即可");
	        $form->select('package_id', '套餐类型')->setWidth(5, 2)->options(DecoCompanyOrder::PACKAGE_DESC)->default(DecoCompanyOrder::PACKAGE_DEFAULT)->required($required_text);
	        $form->date('pay_time', '实际支付时间')->default(date('Y-m-d'))->help('<label style="color: brown">默认为当天，请填写用户实际的付款时间</label>')
		        ->setWidth(5, 2)->required($required_text);
	        $form->select('pay_platform', '支付方式')->setWidth(5, 2)->options(DecoCompanyOrder::PAY_PLATFORM_DESC)->default(DecoCompanyOrder::PAY_PLATFORM_BANK)->required($required_text);
	        $form->select('refund_status', '退款状态')->setWidth(5, 2)->options(DecoCompanyOrder::REFUND_STATUS)->default(DecoCompanyOrder::NOT_REFUND)->required($required_text);
	        $form->text('real_price', '实付金额（元）')->setWidth(5, 2)->default(self::DEFAULT_AMOUNT)->required($required_text);
	        $form->text('certificate_number', '付款凭证编号')->setWidth(5, 2)->required($required_text);
	        $form->imgUpload('certificate_number_pic', '付款凭证图片（必传）', false, [
		        'imgType' => ImgUrl::APPTYPE_OP,
		        'imgSize' => ImgUrl::IMAGE_SIZE_OP_ORI,
	        ])->setWidth(5, 2);
        }
        $form->confirm('务必仔细检查填写信息是否有误，提交后无法修改，要不再检查检查？');

        $form->action('/admin/DecoCompany/order/save');

        return $form->render();
    }

    // 提交
    public function save(Request $request)
    {
        $params = $request->all();
        $user_info = Member::get('*', [
        	'uid' => $params['uid']
        ]);

        if (empty($user_info)) {
	        $error = new MessageBag([
		        'title' => '该用户不存在'
	        ]);

	        return back()->withInput()->with(compact('error'));
        }

	    // 付款凭证图片
	    if (empty($params['certificate_number_pic'])) {
		    $error = new MessageBag([
			    'title' => '请上传付款凭证'
		    ]);

		    return back()->withInput()->with(compact('error'));
	    }

	    $auth_info = DecoCompanyAuth::getByUid($params['uid']);
	    if (empty($auth_info)) {
		    $error = new MessageBag([
			    'title' => '认证信息中未查找到此账号，请检查用户是否提交了入驻申请！'
		    ]);

		    return back()->withInput()->with(compact('error'));
	    } else {
		    if (empty($params['id']) && $auth_info['datum_status'] != DecoCompanyAuth::DATUM_PASS) {
			    $error = new MessageBag([
				    'title' => '认证资料未审核通过，请联系装修公司补充资料后再录入订单'
			    ]);

			    return back()->withInput()->with(compact('error'));
		    }
	    }

        // 142手机号注册
        $phone = mPhone::getByUid($params['uid']);
        if ($params['real_price'] == 0 && $phone && strpos($phone['hidden_phone'], sIdentifyingcode::DEBUG_PHONE_PREFIX) !== 0) {
	        $error = new MessageBag([
		        'title' => '付款金额不对；内部测试号请用142注册'
	        ]);

	        return back()->withInput()->with(compact('error'));
        }

        // 录入新订单
        if (!isset($params['id'])) {

            // 续费
            if ($user_info['type'] == Member::AUTH_DECO_COMPANY) {
                // 时间校验
                if (ceil(($auth_info['auth_expire_time']-time())/(3600*24)) > self::RENEWAL_SPLIT_DAY) {
                    $error = new MessageBag([
                        'title' => '该账号是已认证装企，未到续费时间，不支持重复录入'
                    ]);
                    return back()->withInput()->with(compact('error'));
                }

            } else if (!in_array($user_info['type'], [Member::USER_COMMON, Member::AUTH_USER_UNAUTH_DESIGNER])) {
                // 新认证 身份类型校验
                $error = new MessageBag([
                    'title' => '该账号不是普通用户或未认证设计师，请联系客户重新申请认证'
                ]);
                return back()->withInput()->with(compact('error'));

            }

        }

        $now = time();
        if(isset($params['id']) ) {
            $dsn = DecoCompanyOrder::get('dsn', ['id' => $params['id']]);
            if (empty($dsn)) {
                $error = new MessageBag([
                    'title' => '订单dsn为空'
                ]);
                return back()->withInput()->with(compact('error'));
            }

            $rs = DecoCompanyOrder::updateOrder($params['id'], [
            	'refund_status' => $params['refund_status'],
            	'update_time' => $now,
	            'admin_id' => Admin::user()->id,
	            'admin_name' => Admin::user()->username,
            ]);

        } else {
	        $dsn = OrderService::createOrderSN($params['uid']);

	        $data = [
		        'uid' => $params['uid'],
		        'package_id' => $params['package_id'],
		        'package_name' => DecoCompanyOrder::PACKAGE_DESC[$params['package_id']],
		        'pay_time' => strtotime($params['pay_time']),
		        'dsn' => $dsn,
		        'nick' => $user_info['nick'],
		        'pay_platform' => $params['pay_platform'],
		        'pay_status' => DecoCompanyOrder::PAY_STATUS_PAID,
		        'certificate_number' => $params['certificate_number'],
		        'certificate_number_pic' => $params['certificate_number_pic'] ?: '',
		        'real_price' => $params['real_price'],
		        'product_price' => $params['real_price'],
		        'admin_id' => Admin::user()->id,
		        'admin_name' => Admin::user()->username,
		        'data_status' => DecoCompanyOrder::STATUS_NORMAL,
	        ];
            $rs = DecoCompanyOrder::createOrder($data);
        }

        if($rs) {
            if(isset($params['id'])) {
                $title = '修改成功';
            } else {
                $title = '添加成功';

	            // 付费成功后回调
	            sDecoCompany::afterOrder($user_info['uid'], [
		            'user_type' => $user_info['type'],
		            'auth_status' => $auth_info['auth_status'],
		            'order_sn' => $dsn,
	            ]);
            }

            $success = new MessageBag([
                'title' => $title
            ]);
            return redirect('/admin/DecoCompany/order')->with(compact('success'));
        } else {
            if (isset($params['id'])) {
                $title = '修改失败';
            } else {
                $title = '添加失败';
            }
            $error = new MessageBag([
                'title' => $title
            ]);
	        return back()->withInput()->with(compact('error'));
        }
    }

    public function export(Request $request)
    {
	    $params = $request->all();

	    if ((HhzEnv::isProduction() || HhzEnv::isGray()) && !in_array(Admin::user()->username, self::OPERATOR_LIST)) {
		    $error = new MessageBag([
			    'title' => '您没有权限操作'
		    ]);

		    return back()->withInput()->with(compact('error'));
	    }

	    $condition = [];
	    if (!empty($params['uid'])) {
	    	$condition['uid'] = $params['uid'];
	    }

	    if (!empty($params['pay_status'])) {
	    	$condition['pay_status'] = $params['pay_status'];
	    }

	    if (!empty($params['refund_status'])) {
	    	$condition['refund_status'] = $params['refund_status'];
	    }

	    if (!empty($params['pay_platform'])) {
	    	$condition['pay_platform'] = $params['pay_platform'];
	    }

	    if (!empty($params['create_time']['<='])) {
		    $condition['create_time[<=]'] = $params['create_time']['<='];
	    }

	    if (!empty($params['create_time']['>='])) {
		    $condition['create_time[>=]'] = $params['create_time']['>='];
	    }

	    if (!empty($params['pay_time']['<='])) {
		    $condition['pay_time[<=]'] = $params['pay_time']['<='];
	    }

	    if (!empty($params['pay_time']['>='])) {
		    $condition['pay_time[>=]'] = $params['pay_time']['>='];
	    }

	    $condition['ORDER'] = ['id' => 'DESC'];

	    $lists = DecoCompanyOrder::select('*', $condition);
	    $lists = is_array($lists) ? $lists : [];

	    if (empty($lists)) {
		    $error = new MessageBag([
			    'title' => '暂无数据可导出'
		    ]);

		    return back()->with(compact('error'));
	    }

	    $user_ids = array_column($lists, 'uid');
	    $member_info = Member::getUsers($user_ids);

	    $data = [];
	    foreach ($lists as $item) {
			$row = [
				'dsn' => $item['dsn'],
				'uid' => $item['uid'],
				'nick' => empty($member_info[$item['uid']]['nick']) ? '' : $member_info[$item['uid']]['nick'],
				'package_name' => $item['package_name'],
				'pay_platform' => DecoCompanyOrder::PAY_PLATFORM_DESC[$item['pay_platform']],
				'pay_status' => DecoCompanyOrder::PAY_STATUS_DESC[$item['pay_status']],
				'refund_status' => DecoCompanyOrder::REFUND_STATUS[$item['refund_status']],
				'certificate_number' => $item['certificate_number'],
				'real_price' => $item['real_price'],
				'create_time' => date('Y-m-d H:i:s', $item['create_time']),
				'pay_time' => date('Y-m-d', $item['pay_time']),
				'start_date' => $item['start_date'],
				'end_date' => $item['end_date'],
				'admin_name' => $item['admin_name'],
				'customer' => DecoCompanyPayService::countAllByUid($item['uid']) > 1 ? '老用户' : '新用户',
			];
			$data[] = $row;
	    }

	    // 设置列宽
	    $letter = range('A', 'O');
	    $header = [
		    '订单号', 'uid', '装修公司昵称', '服务套餐名称', '支付方式', '支付状态', '退款状态', '付款凭证编号', '实付金额（元）', '录入时间', '实际支付时间', '服务生效时间', '服务到期时间',
		    '操作人', '新/老用户'
	    ];
	    $excel = new DownExcel();
	    $excel->setFileName('装修公司订单表 - ' . date('YmdHis'));
	    $excel->setSheetTitle('装修公司订单表');

	    // 设置列宽
	    $width = [
		    'A' => 20,
		    'B' => 15,
		    'C' => 35,
		    'D' => 15,
		    'E' => 12,
		    'F' => 12,
		    'G' => 12,
		    'H' => 35,
		    'I' => 15,
		    'J' => 23,
		    'K' => 15,
		    'L' => 16,
		    'M' => 16,
		    'N' => 16,
		    'O' => 12,
	    ];

	    $excel->setWidth($width);
	    $excel->setDefaultStyleAlignment();

	    foreach ($header as $key => $value) {
		    // 设置字体
		    $excel->setFrontName($letter[$key]);
		    // 设置加粗
		    $excel->setFrontBold("$letter[$key]1");
		    // 设置大小
		    $excel->setFrontSize($letter[$key]);
	    }

	    $excel->create($data, $header);
    }
}
